#include "sys_pub.h"
#include "modbus_rtu.h"
#include "uart_comm.h"

// Modbus device address
#define MODBUS_SLAVE_ADDR 0x01
// System tick interval (10ms)
#define TICK_INTERVAL_MS 10
// Modbus timeout (50ms)
#define MODBUS_TIMEOUT_MS 50
static ModbusContext modbus_ctx1;
static ModbusCallbacks modbus_cbs1;
static ModbusContext modbus_ctx3;
static ModbusCallbacks modbus_cbs3;
__weak bool modbus_register_handler(uint16_t address, uint16_t *value, bool is_write)
{
    return true;
}
// UART protocol parsing function



protocol_result_typeDef modbus_ctx1_protocol_parse(uint8_t *rx_data, uint16_t rx_len,
                                                  uint8_t *tx_data, uint16_t *tx_len)
{
    // Pass received bytes to Modbus handler
    for (uint16_t i = 0; i < rx_len; i++)
    {
        modbus_receive_byte(&modbus_ctx1, rx_data[i]);
    }
    // Process complete Modbus frame
    if (!modbus_ctx1.rx_state.frame_complete)
    {
        return PROTOCOL_RESULT_INCOMPLETE;
    }
    modbus_process_frame(&modbus_ctx1, &modbus_cbs1);
    return PROTOCOL_RESULT_OK;
   
}
protocol_result_typeDef modbus_ctx3_protocol_parse(uint8_t *rx_data, uint16_t rx_len,
                                                  uint8_t *tx_data, uint16_t *tx_len)
{
    // Pass received bytes to Modbus handler
    for (uint16_t i = 0; i < rx_len; i++)
    {
        modbus_receive_byte(&modbus_ctx3, rx_data[i]);
    }

    // Process complete Modbus frame
    if (!modbus_ctx3.rx_state.frame_complete)
    {
         return PROTOCOL_RESULT_INCOMPLETE;
    }
    modbus_process_frame(&modbus_ctx3, &modbus_cbs3);
    return PROTOCOL_RESULT_OK;

}

// Modbus send callback implementation
void modbus_uart3_send_impl(const uint8_t *data, uint16_t length)
{
    // Send data via UART3
    for (uint16_t i = 0; i < length; i++)
    {
        UART3_SendData8(data[i]);
        while (UART3_GetFlagStatus(UART3_FLAG_TXE) == RESET);
    }
}
void modbus_uart1_send_impl(const uint8_t *data, uint16_t length)
{
    // Send data via UART3
    for (uint16_t i = 0; i < length; i++)
    {
        UART1_SendData8(data[i]);
        while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
    }
}
void modbus_uart3_init()
{
    modbus_init(&modbus_ctx3, MODBUS_SLAVE_ADDR, TICK_INTERVAL_MS, MODBUS_TIMEOUT_MS);
    modbus_cbs3.send = modbus_uart3_send_impl;
    modbus_cbs3.coil_handler = NULL;
    modbus_cbs3.register_handler = modbus_register_handler;
    uart3_hw_init(115200, modbus_ctx3_protocol_parse);
}
void modbus_uart3_process()
{
    modbus_tick(&modbus_ctx3);
    uart3_protocol_process();
}
// void modbus_uart1_start()
// {
//     modbus_init(&modbus_ctx1, MODBUS_SLAVE_ADDR, TICK_INTERVAL_MS, MODBUS_TIMEOUT_MS);
//     modbus_cbs1.send = modbus_uart1_send_impl;
//     modbus_cbs1.coil_handler = NULL;
//     modbus_cbs1.register_handler = modbus_register_handler;
//     uart1_hw_init(115200, modbus_ctx1_protocol_parse);
// }


// TASK_EXPORT(modbus, modbus_start, modbus_process, 10);